package com.shop.cloud.common.mybatis;

import java.beans.PropertyEditorSupport;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import com.shop.cloud.common.mybatis.BaseEntity;
import com.shop.cloud.util.DateUtils;
import com.shop.cloud.util.MagicConstants;
import com.shop.cloud.util.Objects;
import com.shop.cloud.util.Page;
import com.shop.cloud.util.URLUtils;

/**
 * 基础控制器 其他控制器继承此控制器获得日期字段类型转换和防止XSS攻击的功能
 */
public class BaseController {
	
	protected final Logger logger = Logger.getLogger(getClass());
	
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		// String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
		binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				setValue(StringUtils.isEmpty(text) ? null : URLUtils.decodeURL(StringEscapeUtils.escapeHtml4(text.trim())));
			}

			@Override
			public String getAsText() {
				Object value = getValue();
				return value != null ? value.toString() : null;
			}
		});
		// Date 类型转换
		binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				Date date = DateUtils.parseDate(text);
				setValue(date == null ? null : new Timestamp(date.getTime()));
			}
		});
		// Timestamp 类型转换
		binder.registerCustomEditor(Timestamp.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				Date date = DateUtils.parseDate(text);
				setValue(date == null ? null : new Timestamp(date.getTime()));
			}
		});
	}

	public <T extends BaseEntity> Page<T> getPage(HttpServletRequest request) {
		int pageIndex = 1;
		int pageSize = 100;
		String orderBy = "id asc";
		if (StringUtils.isNotEmpty(request.getParameter("pageSize"))) {
			pageSize = Objects.strToInt(request.getParameter("pageSize"), pageSize);
		}
		if (StringUtils.isNotEmpty(request.getParameter("pageIndex"))) {
			pageIndex = Objects.strToInt(request.getParameter("pageIndex"), 1);
		}
		if (StringUtils.isNotEmpty(request.getParameter("orderBy"))) {
			orderBy = request.getParameter("orderBy").toString();
		}
		Page<T> param = new Page<T>(pageIndex, pageSize);
		param.setOrderBy(orderBy);
		return param;
	}

	public <T> HashMap<String, Object> getPageMap(HttpServletRequest request) {
		int limitStart = 0;
		int pageSize = 1000000;
		int pageIndex = 1;

		String orderBy = "id asc";
		if (StringUtils.isNotEmpty(request.getParameter("pageSize"))) {
			pageSize = Objects.strToInt(request.getParameter("pageSize"), pageSize);
		}
		if (StringUtils.isNotEmpty(request.getParameter("pageIndex"))) {
			pageIndex = Objects.strToInt(request.getParameter("pageIndex"), 1);
			limitStart = (pageIndex - 1) * pageSize;
		}
		if (StringUtils.isNotEmpty(request.getParameter("orderBy"))) {
			orderBy = request.getParameter("orderBy").toString();
		}
		HashMap<String, Object> param = getParamMap(request);
		param.put(MagicConstants.LIMIT_START, limitStart);
		param.put(MagicConstants.LIMIT_END, pageIndex * pageSize);
		param.put("orderBy", orderBy);
		return param;
	}

	public <T> HashMap<String, Object> getPageMapNew(HttpServletRequest request,int pageSizeNew,int pageIndexNew) {
		int limitStart = 0;
		int pageSize = 0;
		int pageIndex = 0;
		if(Integer.toString(pageSizeNew)!=null && pageSizeNew!=0 && Integer.toString(pageSizeNew)!=""){
			pageSize = pageSizeNew;
		}
		if(Integer.toString(pageIndexNew)!=null && Integer.toString(pageIndexNew)!=""){
			pageIndex = pageIndexNew;
		}

		String orderBy = "id asc";
		if (StringUtils.isNotEmpty(request.getParameter("pageSize"))) {
			pageSize = Objects.strToInt(request.getParameter("pageSize"), pageSize);
		}
		if (StringUtils.isNotEmpty(request.getParameter("pageIndex"))) {
			pageIndex = Objects.strToInt(request.getParameter("pageIndex"), 1);
			limitStart = (pageIndex - 1) * pageSize;
		}
		if (StringUtils.isNotEmpty(request.getParameter("orderBy"))) {
			orderBy = request.getParameter("orderBy").toString();
		}
		HashMap<String, Object> param = getParamMap(request);
		param.put(MagicConstants.LIMIT_START, (pageIndex-1) * pageSize);
		param.put(MagicConstants.LIMIT_END, pageSize);
		param.put("orderBy", orderBy);
		return param;
	}

	public <T> HashMap<String, Object> getParamMap(HttpServletRequest request) {
		HashMap<String, Object> param = new HashMap<String, Object>();
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String p = parameterNames.nextElement();
			String[] parameters = request.getParameterValues(p);
			if (StringUtils.isNotEmpty(p) && parameters != null) {
				String string = StringUtils.join(Arrays.asList(parameters), ",");
				if (!StringUtils.isEmpty(string)) {
					param.put(p, URLUtils.decodeURL(string));
				}
			}
		}
		return param;
	}
	
	@SuppressWarnings("deprecation")
	protected String getStringDateTime(Timestamp time) {
    		if(time == null) {
			return "";
		}
    		return String.format("%04d-%02d-%02d %02d:%02d:%02d", 
			    				time.getYear() + 1900,
			    				time.getMonth() + 1,
    							time.getDate(),
    							time.getHours(),
    							time.getMinutes(),
    							time.getSeconds());
    }
    
    @SuppressWarnings("deprecation")
    protected String getStringDate(Timestamp time) {
    		if(time == null) {
    			return "";
    		}
		return String.format("%04d-%02d-%02d", 
				time.getYear() + 1900,
				time.getMonth() + 1,
				time.getDate());
    }
    
    @SuppressWarnings("deprecation")
    protected String getStringDate(Date time) {
    		if(time == null) {
			return "";
		}
		return String.format("%04d-%02d-%02d", 
							time.getYear(),
							time.getMonth(),
							time.getDay());
    }
    
    @SuppressWarnings("deprecation")
	protected String getStringTime(Time time) {
    		if(time == null) {
			return "";
		}
		return String.format("%02d:%02d:%02d", 
							time.getHours(),
							time.getMinutes(),
							time.getSeconds());
    }

	
}
